﻿using System;
using System.Linq;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Collections.Generic;
using ConsolidationTool.Common;
using ConsolidationTool.WebParts.Layouts.AjaxServices;

namespace ConsolidationTool.WebParts.Layouts.CReport
{
    public partial class ARAPIntercoReport : FSReportBase
    {
        public class ARAPIntercoEntity : ICloneable
        {
            public ARAPIntercoEntity()
            {
                AccountCode = string.Empty;
            }

            public string AccountCode { get; set; }
            public string Description { get; set; }
            public string Seller { get; set; }
            public string Buyer { get; set; }
            public string LocalCurrecny { get; set; }
            public string Seller_Amount { get; set; }
            public string Buyer_Amount { get; set; }
            public string Conso_Currency { get; set; }
            public string Conso_Seller_Amount { get; set; }
            public string Conso_Buyer_Amount { get; set; }

            public int Index { get; set; }

            public object Clone()
            {
                return this.MemberwiseClone();
            }

            public bool isSeller { get; set; }

            public bool isBuyer { get; set; }
        }

        public override ControlTemplates.CommonEntitySelector TopSelector
        {
            get
            {
                return commonEntitySelector as ControlTemplates.CommonEntitySelector;
            }
        }

        private void CreateEntityMapping()
        {
            var web = SPContext.Current.Web;
            var list = web.Lists["Entity"];
            int itemCount = list.Items.Count;
            for (int i = 0; i < itemCount; i++)
            {
                var item = list.Items[i];
                EntityMapping.Add(item["Title"] + "", item["ConsolidationTool_CoCd"] + "");
                CoCdMapping.Add(item["ConsolidationTool_CoCd"] + "", item["Title"] + "");
            }
        }

        public Dictionary<string, string> EntityMapping = new Dictionary<string, string>();
        public Dictionary<string, string> CoCdMapping = new Dictionary<string, string>();
        public Dictionary<string, int> IndexMapping = new Dictionary<string, int>();
        public Dictionary<string, string> TitleMapping = new Dictionary<string, string>();

        protected void Page_Load(object sender, EventArgs e)
        {
        }
        /* 
         */
        public override void GenerateReport_Click(object sender, EventArgs e)
        {
            CreateEntityMapping();
            rateServices = new RateServices();
            currentMonthRate = rateServices.LoadExchangeRate("Actual", CEntity.Year + "", CEntity.Month + "", "Original");

            /**/
            TitleMapping.Add("AR02010102", "Trade accounts receivable - Internal Asia");
            TitleMapping.Add("AP02010102", "Trade account payable-gross - Internal Asia");
            TitleMapping.Add("AR02010202", "Interest receivable - Internal Asia");
            TitleMapping.Add("AP02010202", "Interest payable - Internal Asia");
            TitleMapping.Add("AP02010302", "Fixed assets payable - Internal Asia");
            TitleMapping.Add("AR02010402", "Other receivable - Internal Asia");
            TitleMapping.Add("AP02010502", "Other payable - Internal Asia");

            IndexMapping.Add("AR02010102", 1000000);
            IndexMapping.Add("AP02010102", 1000000);
            IndexMapping.Add("AR02010202", 2000000);
            IndexMapping.Add("AP02010202", 2000000);
            IndexMapping.Add("AP02010302", 3000000);
            IndexMapping.Add("AR02010402", 4000000);
            IndexMapping.Add("AP02010502", 4000000);

            var web = SPContext.Current.Web;
            var list = web.Lists["Actual_ARAP"];
            var query = new SPQuery()
            {
                Query = string.Format(@" <Where>
                                            <And>
                                                <Eq>
                                                <FieldRef Name='Year' />
                                                <Value Type='Integer'>{0}</Value>
                                                </Eq>
                                                <Eq>
                                                <FieldRef Name='Month' />
                                                <Value Type='Integer'>{1}</Value>
                                                </Eq>
                                            </And>
                                        </Where>", CEntity.Year, CEntity.Month)
            };
            var items = list.GetItems(query);
            int itemCount = items.Count;
            if (itemCount == 0) return;

            var allIntercoData = new List<ARAPIntercoEntity>();

            for (int i = 0; i < itemCount; i++)
            {
                var item = new CacheSPItem(items[i]);
                allIntercoData.AddRange(InitIntercoEntity(item, 0)); //index every entity is start with 1000*i
            }

            var newOrderIntercoData = allIntercoData.OrderBy(p => p.Index).ToList();


            var newObj = new List<ARAPIntercoEntity>();
            newOrderIntercoData.Where(p => p.isSeller).ToList().ForEach(p =>
            {

                newObj.Add(p.Clone() as ARAPIntercoEntity);
                var buyer = newOrderIntercoData.FirstOrDefault(a => a.isBuyer && a.Seller == p.Seller
                    && a.Buyer == p.Buyer
                    && a.AccountCode.Substring(2) == p.AccountCode.Substring(2));
                if (buyer != null)
                    newObj.Add(buyer.Clone() as ARAPIntercoEntity);
                else
                    newObj.Add(new ARAPIntercoEntity() { AccountCode = p.AccountCode, Description= "Buyer not found", Index = p.Index });

            });

            var newBuyerObj = new List<ARAPIntercoEntity>();
            newOrderIntercoData.ForEach(p => newBuyerObj.Add(p.Clone() as ARAPIntercoEntity));

            newOrderIntercoData.Where(p => p.isBuyer).ToList().ForEach(p =>
            {
                if (p.AccountCode == "AP02010302") {

                    var newOne = p.Clone() as ARAPIntercoEntity;
                    var index = newObj.FindLastIndex(a => a.Index == 2000000) + 1;
                    // index += (newObj.Count >= (index + 1)) ? 1 : 0;

                    newObj.Insert(index, newOne);
                }
                else
                {
                    var seller = newBuyerObj.FirstOrDefault(a => a.isSeller && a.Seller == p.Seller
                        && a.Buyer == p.Buyer
                        && a.AccountCode.Substring(2) == p.AccountCode.Substring(2));

                    if (seller == null)
                    {
                        var newOne = p.Clone() as ARAPIntercoEntity;
                        var index = newObj.FindLastIndex(a => a.Index == newOne.Index) + 1;
                        // index += (newObj.Count >= (index + 1)) ? 1 : 0;

                        newObj.Insert(index, new ARAPIntercoEntity() { AccountCode = newOne.AccountCode, Description = "Seller not found", Index = newOne.Index });
                        newObj.Insert(index + 1, newOne);
                    }
                }

            });



            //var fix = 1;
            //for (int i = 0; i < newObj.Count; i++)
            //{
            //    var c = newObj[i];
            //    if (c.AccountCode.IsNullOrEmpty()) continue;

            //    if (c.AccountCode.StartsWith("AR") && (!newObj[i + 1 - (fix-1)].AccountCode.StartsWith("AP")))
            //    {
            //        newOrderIntercoData.Insert(i + fix, new ARAPIntercoEntity() { AccountCode = "Undefined AP!" });
            //        fix++;
            //    }

            //} 

            //newObj = new List<ARAPIntercoEntity>();
            //newOrderIntercoData.ForEach(p => newObj.Add(p.Clone() as ARAPIntercoEntity));

            //fix = 0;
            //for (int i = 0; i < newObj.Count; i++)
            //{
            //    var c = newObj[i];
            //    if (c.AccountCode.IsNullOrEmpty()) continue;

            //    if (c.AccountCode.StartsWith("AP") && (!newObj[i - 1].AccountCode.StartsWith("AR")))
            //    {
            //        newOrderIntercoData.Insert(i + fix, new ARAPIntercoEntity() { AccountCode = "Undefined AR!" });
            //        fix++;
            //    }

            //}

            int fix = 1;
            int lastIndexTrade = newObj.FindLastIndex(p => p.AccountCode == "AP02010102");
            int lastIndexInterest = newObj.FindLastIndex(p => p.AccountCode == "AP02010202");
            int lastIndexFixed = newObj.FindLastIndex(p => p.AccountCode == "AP02010302");
            //int lastIndexOther = newObj.FindLastIndex(p => p.AccountCode == "AR02010402");
            if (lastIndexTrade > 0)
            {
                newObj.Insert(lastIndexTrade+fix, new ARAPIntercoEntity());
                fix++;
            }
            if (lastIndexInterest > 0)
            {
                newObj.Insert(lastIndexInterest+fix, new ARAPIntercoEntity()); 
                fix++;
            }
            if (lastIndexFixed > 0)
            {
                newObj.Insert(lastIndexFixed + fix, new ARAPIntercoEntity());
                fix++;
            }
            //if (lastIndexOther > 0)
            //{
            //    newObj.Insert(lastIndexOther + fix, new ARAPIntercoEntity());
            //    fix++;
            //}

            gvActualIntercoReport.DataSource = newObj;
            gvActualIntercoReport.DataBind();
        }

        private List<ARAPIntercoEntity> InitIntercoEntity(CacheSPItem item, int index)
        {
            var temp = new List<ARAPIntercoEntity>();

            var i = 1;
            item.KoFields.Where(p => p.issubrow).ToList().ForEach(p =>
            {
                var parentAccountCode = p.accountcode.Split('-').First();
                var isSeller = TitleMapping[parentAccountCode].IndexOf("receivable") != -1; //if current node is seller 

                var node = new ARAPIntercoEntity() { LocalCurrecny = item.Currency, Conso_Currency = "KEUR", AccountCode = parentAccountCode, Description = TitleMapping[parentAccountCode] };
                if (isSeller)
                {
                    node.isSeller = isSeller;
                    node.Seller = item.CoName;
                    node.Buyer = CoCdMapping[p.entity];
                    node.Seller_Amount = p.CM;
                    node.Conso_Seller_Amount = GetRateValue(item, p.CM);
                }
                else
                {
                    node.isBuyer = true;
                    node.Buyer = item.CoName;
                    node.Seller = CoCdMapping[p.entity];
                    node.Buyer_Amount = p.CM;
                    node.Conso_Buyer_Amount = GetRateValue(item, p.CM);
                }

                var nodeIndex = IndexMapping[parentAccountCode];

                node.Index = nodeIndex;

                temp.Add(node);
            });

            return temp;
        }

        private RateServices rateServices;
        List<ExchangeRate> currentMonthRate;
        private string GetRateValue(CacheSPItem item, string p)
        {
            var rateItem = currentMonthRate.FirstOrDefault(c => c.FC == item.LocalCurrency);
            var value = Utilities.Division(p, rateItem.TryGetValue("CM") + "", false);
            return value;
        }

    }
}
